home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Meeting Pearls 2
/
Meeting Pearls Vol. II (1995)(GTI - Schatztruhe)[!].iso
/
Pearls
/
comm
/
Envoy
/
Conf
/
tk.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-04-22
|
35KB
|
744 lines
/*************************************************************************
Conference Server/Service written by Jeffrey A. Litz
litz@cs.uwp.edu -or- Jeff_Litz@EDTNG.Kenosha.WI.US
Copyright ©1994 JL Productions.
*************************************************************************/
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/ports.h>
#include <exec/semaphores.h>
#include <exec/io.h>
#include <devices/printer.h>
#include <devices/timer.h>
#include <devices/parallel.h>
#include <devices/serial.h>
#include <intuition/intuition.h>
#include <intuition/classes.h>
#include <intuition/classusr.h>
#include <intuition/imageclass.h>
#include <intuition/gadgetclass.h>
#include <libraries/gadtools.h>
#include <graphics/displayinfo.h>
#include <graphics/gfxbase.h>
#include <clib/intuition_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/graphics_protos.h>
#include <envoy/nipc.h>
#include <envoy/services.h>
#include <proto/intuition.h>
#include <pragmas/exec_pragmas.h>
#include <pragmas/nipc_pragmas.h>
#include <pragmas/dos_pragmas.h>
#include <pragmas/utility_pragmas.h>
#include <utility/tagitem.h>
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>
#include <clib/nipc_protos.h>
#include <clib/alib_protos.h>
#include <clib/utility_protos.h>
#include "string.h"
extern KPrintF(STRPTR,...);
/*************************************************************************
Some structures & definitions for the conference service.
Should go into a .h file.
*************************************************************************/
#include "tkbase.h"
#define TKCMD_TALK 1
#define TKCMD_ABORT 2
#define TKCMD_DATA 3
#define TKCMD_CONFERENCE 4
#define TKCMD_CONDATA 5
#define TKCMD_CONEND 6
#define TKCMD_CONLIST 7
#define TKCMD_CLDATA 8
#define TKCMD_CLEND 9
#define TKCMD_MALIST 10
#define TKCMD_STATUS 11
#define TKCMD_PRIVATE 12
struct Con_Node
{
struct Node cnode;
UBYTE con_name[32];
struct List machine_list;
ULONG flags;
};
struct Hide_Node
{
struct Node hnode;
UBYTE h_name[32];
ULONG mode;
};
struct Machine_Node
{
struct Node mnode;
UBYTE m_id[8];
UBYTE m_name[32];
UBYTE alias[32];
struct List hide_list;
ULONG flags;
void *s_entity;
};
struct TagItem cbtags[2] =
{
ENT_AllocSignal, NULL,
TAG_END, 0
};
struct TagItem ttags[3] =
{
TRN_AllocReqBuffer,516,
TRN_AllocRespBuffer,4,
TAG_END, 0
};
extern STRPTR TKSUser;
extern STRPTR TKSPassword;
extern STRPTR TKSEntityName;
extern ULONG TKSSignalMask;
extern ULONG TKSError;
extern struct Task *TKSSMProc;
extern TKSServer(void);
extern struct Node *CFindName(struct List *cc_list,UBYTE *string);
/**************************************************************************
StartService() - Starts the service.
Services Manager calls this function to attempt to start the service.
INPUTS: TagList passed in by Services Manager
OUTPUT: Error Code - Non Zero Means Error
**************************************************************************/
ULONG __saveds ASM StartService(REG(a0) struct TagItem *st_list)
{
struct TagItem cptags[3];
struct Process *lpdproc;
BOOL status = FALSE;
UBYTE sigbit;
struct TagItem *tag;
/* Check to see if service is already open */
if(!TKSBase->TKS_Entity)
{
/* Nope - Try starting it up */
if(sigbit = AllocSignal(-1L))
{
TKSSMProc = FindTask(0L);
TKSSignalMask = (1L<<sigbit);
cptags[0].ti_Tag = NP_Entry;
cptags[0].ti_Data = (ULONG) TKSServer;
cptags[1].ti_Tag = NP_Name;
cptags[1].ti_Data = (ULONG) "CF Daemon";
cptags[2].ti_Tag = TAG_DONE;
cptags[2].ti_Data = NULL;
/* Process tags passed in by services manager */
if(tag=FindTagItem(SSVC_UserName,st_list))
{
TKSUser = (STRPTR) tag->ti_Data;
}
if(tag=FindTagItem(SSVC_Password,st_list))
{
TKSPassword = (STRPTR) tag->ti_Data;
}
if(tag=FindTagItem(SSVC_EntityName,st_list))
{
TKSEntityName = (STRPTR) tag->ti_Data;
}
/* Try to start the process */
if(lpdproc = CreateNewProc((struct TagItem *)cptags))
{
Wait(1L<<sigbit);
status = TRUE;
}
FreeSignal(sigbit);
}
}
else
{
/* Service process already running... simply pass back its entity name */
if(tag=FindTagItem(SSVC_EntityName,st_list))
{
strcpy((STRPTR)tag->ti_Data,"CF_Service");
TKSError = 0;
} else
{
TKSError = -1;
}
}
return(TKSError);
}
/*************************************************************************
GetServiceAttrsA() - Get service attributes
Required to return the name of the service in tag SVCAttrs_Name
INPUTS: TagList from services manager to process/update
*************************************************************************/
VOID ASM GetServiceAttrsA(REG(a0) struct TagItem *tagList)
{
struct TagItem *ti;
if(ti=FindTagItem( SVCAttrs_Name, tagList))
{
strcpy((STRPTR)ti->ti_Data,"Conf_Service");
}
}
/**************************************************************************
Server() - Actual guts of the service
The Conference Service Main Routine. Keeps track of all conferences,
who in them, the "status" of each user, etc.
Waits for any incoming transcation from our public entity.
Called by an ASM stub called TKSServer.
INPUTS: A0 - UserName, A1 - Password, A2 - EntityName
OUTPUT: Global Var TKSError (only if a startup error occurs)
**************************************************************************/
VOID ASM Server(REG(a0) STRPTR userName,
REG(a1) STRPTR password,
REG(a2) STRPTR EntityName)
{
/* Quite a few variables - should be corrected with allocmen() */
struct Library *SvcBase;
ULONG CON_ID;
ULONG signals;
ULONG waitmask;
ULONG StartupError;
ULONG ent_sigbit;
UBYTE host_name[256];
UBYTE con_name[256],hos_name[256],machine_id[256],alias[256],machine_name[256];
UBYTE pri_msg[512];
UBYTE done;
UWORD cnt;
ULONG mem_p,error,cycle_mode;
void *entity,*t_entity,*s_entity;
struct Transaction *trans,*a_trans;
struct List conference_list;
struct Con_Node *c_node,*c_node2;
struct Machine_Node *m_node,*m2_node,*mm_node,*m_node2;
struct Hide_Node *m3_node,*m4_node;
struct Hide_Node *h_node,*h_node2;
struct TagItem cetags[4];
ULONG m3mode,m4mode;
/* Initialize a bunch of things */
geta4();
cetags[0].ti_Tag = ENT_Name;
cetags[0].ti_Data = (ULONG) "CF_Service";
cetags[1].ti_Tag = ENT_Public;
cetags[1].ti_Data = (ULONG) TRUE;
cetags[2].ti_Tag = ENT_AllocSignal;
cetags[2].ti_Data = (ULONG) &ent_sigbit;
cetags[3].ti_Tag = TAG_END;
cetags[3].ti_Data = (ULONG) NULL;
ent_sigbit = 0;
CON_ID = 0;
NewList(&conference_list);
StartupError = -1;
/* Start of service */
if(SvcBase = OpenLibrary("conf.service", 0L))
{
/* Create our entity for everyone to communicate with us */
if(entity = CreateEntityA((struct TagItem *) cetags))
{
/* Find out who we are */
GetHostName(entity,host_name,255);
if(t_entity=CreateEntityA((struct TagItem *) cbtags))
{
/* Alloc our transaction */
if(a_trans=AllocTransactionA((struct TagItem *) ttags))
{
/* Everything allocated - setup and signal we are ready */
TKSBase->TKS_Entity = entity;
strcpy(EntityName,"CF_Service");
TKSError = StartupError = 0;
Signal(TKSSMProc, TKSSignalMask);
waitmask = (1<<ent_sigbit);
done = 0;
/* Wait for a transaction */
while(TRUE)
{
signals = Wait(waitmask);
if(signals & (1<<ent_sigbit))
{
if(trans = GetTransaction(entity))
{
/* Process a TKCMD_CONFERENCE Transaction */
/* Create or enter a conference */
if(trans->trans_Command == TKCMD_CONFERENCE)
{
error=1;
strcpy(con_name,(UBYTE *)trans->trans_RequestData+4);
strcpy(hos_name,(UBYTE *)trans->trans_RequestData+36);
strcpy(alias,(UBYTE *)trans->trans_RequestData+68);
if(s_entity = FindEntity(hos_name,con_name,t_entity,NULL))
{
if(c_node=(struct Con_Node *)CFindName(&conference_list,con_name))
{
if(!CFindName(&c_node->machine_list,hos_name))
{
if(m_node=AllocMem(sizeof(struct Machine_Node),0))
{
strcpy(m_node->m_name,hos_name);
strcpy(m_node->alias,alias);
m_node->mnode.ln_Name=m_node->m_id;
m_node->flags=0;
m_node->s_entity=s_entity;
NewList(&m_node->hide_list);
sprintf(m_node->m_id,"%ld",CON_ID);
AddTail(&c_node->machine_list,(struct Node *)m_node);
error=0;
}
}
}
else
{
if(c_node=(struct Con_Node *)AllocMem(sizeof(struct Con_Node),0))
{
strcpy(c_node->con_name,con_name);
c_node->cnode.ln_Name=c_node->con_name;
c_node->flags=0;
NewList(&c_node->machine_list);
if(m_node=(struct Machine_Node *)AllocMem(sizeof(struct Machine_Node),0))
{
strcpy(m_node->m_name,hos_name);
strcpy(m_node->alias,alias);
m_node->mnode.ln_Name=m_node->m_id;
m_node->flags=0;
m_node->s_entity=s_entity;
NewList(&m_node->hide_list);
sprintf(m_node->m_id,"%ld",CON_ID);
AddTail(&c_node->machine_list,(struct Node *)m_node);
AddTail(&conference_list,(struct Node *)c_node);
error=0;
}
else
{
FreeMem(c_node,sizeof(struct Con_Node));
}
}
}
}
trans->trans_Error=error;
trans->trans_RespDataActual=4;
*(ULONG *)trans->trans_ResponseData=(ULONG) CON_ID;
ReplyTransaction(trans);
++CON_ID;
}
else if(trans->trans_Command == TKCMD_CONDATA)
{
/* Process a TKCMD_CONDATA Transaction */
/* Go through list and distribute data to appropriate machines */
*(ULONG *)(a_trans->trans_RequestData)=*(ULONG *)(trans->trans_RequestData);
strcpy(((UBYTE *)a_trans->trans_RequestData+4),((UBYTE *)trans->trans_RequestData+4));
a_trans->trans_ReqDataActual=strlen(((UBYTE *)a_trans->trans_RequestData+4))+5;
a_trans->trans_Command=TKCMD_CONDATA;
sprintf(machine_id,"%ld",*(ULONG *)trans->trans_RequestData);
ReplyTransaction(trans);
for(c_node=(struct Con_Node *)conference_list.lh_Head;c_node->cnode.ln_Succ;c_node=(struct Con_Node *)c_node->cnode.ln_Succ)
{
if(m_node=(struct Machine_Node *)CFindName(&c_node->machine_list,machine_id))
{
for(m2_node=(struct Machine_Node *)c_node->machine_list.lh_Head;m2_node->mnode.ln_Succ;m2_node=(struct Machine_Node *)m2_node->mnode.ln_Succ)
{
if(stricmp(machine_id,m2_node->m_id))
{
/* Find the node pointer to another machine in the conference */
if( m3_node = (struct Hide_Node *) CFindName(&m_node->hide_list,m2_node->m_name))
{
m3mode=m3_node->mode;
} else
{
m3mode=0;
}
/* Find the node pointer to the machine sending the message */
if(m4_node=(struct Hide_Node *)CFindName(&m2_node->hide_list,m_node->m_name))
{
m4mode=m4_node->mode;
} else
{
m4mode=0;
}
if( ((m3mode==0) && ((m4mode==0) || (m4mode==1))) || ((m3mode==2) && ((m4mode==0) || (m4mode==1))))
{
cnt=2;
while(cnt)
{
a_trans->trans_Timeout=10;
DoTransaction(m2_node->s_entity,t_entity,a_trans);
if(a_trans->trans_Error == 0)
{
break;
}
--cnt;
}
if(!cnt)
{
/* The machine being sent to couldn't be found - remove it!!! */
for(c_node2=(struct Con_Node *)conference_list.lh_Head;c_node2->cnode.ln_Succ;c_node2=(struct Con_Node *)c_node2->cnode.ln_Succ)
{
if(m_node2=(struct Machine_Node *)CFindName(&c_node2->machine_list,m2_node->m_id))
{
Remove((struct Node*)m_node2);
LoseEntity(m_node2->s_entity);
while(h_node2=(struct Hide_Node *)RemHead(&m_node2->hide_list))
{
FreeMem(h_node2,sizeof(struct Hide_Node));
}
FreeMem(m_node2,sizeof(struct Machine_Node));
if(c_node2->machine_list.lh_Head->ln_Succ == NULL)
{
Remove((struct Node *)c_node2);
FreeMem(c_node2,sizeof(struct Con_Node));
}
break;
}
}
}
}
}
}
break;
}
}
}
else if(trans->trans_Command == TKCMD_CONEND)
{
/* Process a TKCMD_CONEND transaction */
/* Leave a conference and remove if last member */
sprintf(machine_id,"%ld",*((ULONG *)trans->trans_RequestData));
for(c_node=(struct Con_Node *)conference_list.lh_Head;c_node->cnode.ln_Succ;c_node=(struct Con_Node *)c_node->cnode.ln_Succ)
{
if(m_node=(struct Machine_Node *)CFindName(&c_node->machine_list,machine_id))
{
Remove((struct Node*)m_node);
LoseEntity(m_node->s_entity);
while(h_node=(struct Hide_Node *)RemHead(&m_node->hide_list))
{
FreeMem(h_node,sizeof(struct Hide_Node));
}
FreeMem(m_node,sizeof(struct Machine_Node));
if(c_node->machine_list.lh_Head->ln_Succ == NULL)
{
Remove((struct Node *)c_node);
FreeMem(c_node,sizeof(struct Con_Node));
}
break;
}
}
ReplyTransaction(trans);
}
else if(trans->trans_Command == TKCMD_CONLIST)
{
/* Return a list of available conferences */
strcpy(hos_name,(UBYTE *)trans->trans_RequestData+4);
s_entity = FindEntity(hos_name,"Conference_List",t_entity,NULL);
if(s_entity)
{
trans->trans_Error=0;
ReplyTransaction(trans);
mem_p=4;
for(c_node=(struct Con_Node *)conference_list.lh_Head;c_node->cnode.ln_Succ;c_node=(struct Con_Node *)c_node->cnode.ln_Succ)
{
strcpy(((UBYTE *)a_trans->trans_RequestData+mem_p),c_node->con_name);
mem_p+=32;
if(mem_p == 516)
{
a_trans->trans_ReqDataActual=516;
a_trans->trans_Command=TKCMD_CLDATA;
a_trans->trans_Timeout=10;
DoTransaction(s_entity,t_entity,a_trans);
mem_p=4;
}
}
if(mem_p != 4)
{
a_trans->trans_ReqDataActual=mem_p;
a_trans->trans_Command=TKCMD_CLDATA;
a_trans->trans_Timeout=10;
DoTransaction(s_entity,t_entity,a_trans);
}
a_trans->trans_ReqDataActual=4;
a_trans->trans_Command=TKCMD_CLEND;
a_trans->trans_Timeout=10;
DoTransaction(s_entity,t_entity,a_trans);
LoseEntity(s_entity);
} else
{
trans->trans_Error=999;
ReplyTransaction(trans);
}
}
else if(trans->trans_Command == TKCMD_MALIST)
{
/* Return a list of members in a conference */
strcpy(con_name,(UBYTE *)trans->trans_RequestData+4);
strcpy(hos_name,(UBYTE *)trans->trans_RequestData+36);
s_entity = FindEntity(hos_name,"Conference_List",t_entity,NULL);
if(s_entity)
{
trans->trans_Error=0;
ReplyTransaction(trans);
mem_p=4;
if(c_node=(struct Con_Node *)CFindName(&conference_list,con_name))
{
for(m_node=(struct Machine_Node *)c_node->machine_list.lh_Head;m_node->mnode.ln_Succ;m_node=(struct Machine_Node *)m_node->mnode.ln_Succ)
{
strcpy(((UBYTE *)a_trans->trans_RequestData+mem_p),m_node->m_name);
strcpy(((UBYTE *)a_trans->trans_RequestData+mem_p+32),m_node->alias);
cycle_mode=0;
for(mm_node=(struct Machine_Node *)c_node->machine_list.lh_Head;mm_node->mnode.ln_Succ;mm_node=(struct Machine_Node *)mm_node->mnode.ln_Succ)
{
if(!stricmp(mm_node->m_name,hos_name))
{
if(h_node=(struct Hide_Node *)CFindName(&mm_node->hide_list,m_node->m_name))
{
cycle_mode=h_node->mode;
break;
}
}
}
*(ULONG *)((UBYTE *)a_trans->trans_RequestData+mem_p+64)=(ULONG)cycle_mode;
mem_p+=68;
if(mem_p == 480)
{
a_trans->trans_ReqDataActual=480;
a_trans->trans_Command=TKCMD_CLDATA;
a_trans->trans_Timeout=10;
DoTransaction(s_entity,t_entity,a_trans);
mem_p=4;
}
}
if(mem_p != 4)
{
a_trans->trans_ReqDataActual=mem_p;
a_trans->trans_Command=TKCMD_CLDATA;
a_trans->trans_Timeout=10;
DoTransaction(s_entity,t_entity,a_trans);
}
}
a_trans->trans_ReqDataActual=4;
a_trans->trans_Command=TKCMD_CLEND;
a_trans->trans_Timeout=10;
DoTransaction(s_entity,t_entity,a_trans);
LoseEntity(s_entity);
} else
{
trans->trans_Error=999;
ReplyTransaction(trans);
}
}
else if(trans->trans_Command == TKCMD_PRIVATE)
{
/* Transmit a private message to a member in x conference on y machine */
strcpy(hos_name,(UBYTE *)trans->trans_RequestData+4);
strcpy(con_name,(UBYTE *)trans->trans_RequestData+36);
strcpy(pri_msg,(UBYTE *)trans->trans_RequestData+68);
*(ULONG *)(a_trans->trans_RequestData)=*(ULONG *)(trans->trans_RequestData);
strcpy(((UBYTE *)a_trans->trans_RequestData+4),((UBYTE *)trans->trans_RequestData+68));
a_trans->trans_ReqDataActual=strlen(((UBYTE *)a_trans->trans_RequestData+4))+5;
a_trans->trans_Command=TKCMD_CONDATA;
ReplyTransaction(trans);
if(c_node=(struct Con_Node *)CFindName(&conference_list,con_name))
{
for(m_node=(struct Machine_Node *)c_node->machine_list.lh_Head;m_node->mnode.ln_Succ;m_node=(struct Machine_Node *)m_node->mnode.ln_Succ)
{
if(!stricmp(m_node->m_name,hos_name))
{
a_trans->trans_Timeout=10;
DoTransaction(m_node->s_entity,t_entity,a_trans);
break;
}
}
}
}
else if(trans->trans_Command == TKCMD_STATUS)
{
/* Change the status of a member in someone's list */
strcpy(machine_name,(UBYTE *)trans->trans_RequestData+4);
strcpy(con_name,(UBYTE *)trans->trans_RequestData+36);
strcpy(hos_name,(UBYTE *)trans->trans_RequestData+68);
cycle_mode=*(ULONG *)((UBYTE *)trans->trans_RequestData+100);
error=1;
if(c_node=(struct Con_Node *)CFindName(&conference_list,con_name))
{
for(m_node=(struct Machine_Node *)c_node->machine_list.lh_Head;m_node->mnode.ln_Succ;m_node=(struct Machine_Node *)m_node->mnode.ln_Succ)
{
if(!stricmp(m_node->m_name,hos_name))
{
error=0;
if(h_node=(struct Hide_Node *)CFindName(&m_node->hide_list,machine_name))
{
h_node->mode=cycle_mode;
}
else if(h_node=(struct Hide_Node *)AllocMem(sizeof(struct Hide_Node),0))
{
h_node->hnode.ln_Name=h_node->h_name;
strcpy(h_node->h_name,machine_name);
h_node->mode=cycle_mode;
AddTail(&m_node->hide_list,(struct Node *)h_node);
}
else
{
error=1;
}
}
}
}
trans->trans_Error=error;
ReplyTransaction(trans);
}
if(conference_list.lh_Head->ln_Succ == NULL)
{
done=1;
}
}
}
if(done)
{
break;
}
}
while(trans = GetTransaction(entity))
{
trans->trans_Error=2;
ReplyTransaction(trans);
}
TKSBase->TKS_Entity = NULL;
a_trans->trans_ReqDataLength=516;
FreeTransaction(a_trans);
}
DeleteEntity(t_entity);
}
DeleteEntity(entity);
}
if(StartupError)
{
TKSError = StartupError;
Signal(TKSSMProc, TKSSignalMask);
}
Forbid();
CloseLibrary(SvcBase);
}
}
/*************************************************************************
CFindName()
Since FindName() is case sensitive, I can't use it...
INPUTS: pointer to a list, pointer to a string to search for
OUTPUT: NULL if not found, otherwise pointer to that node
*************************************************************************/
struct Node *CFindName(struct List *cc_list,UBYTE *string)
{
struct Node *r_value=NULL,*ln;
for(ln=cc_list->lh_Head;ln->ln_Succ;ln=ln->ln_Succ)
{
if(!stricmp(ln->ln_Name,string))
{
r_value=ln;
break;
}
}
return(r_value);
}